package cn.jbit.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

/**
 * 源码学院只为培养优秀的bat程序员而生
 *
 * @author 学员张在成
 * @data 2020/8/9
 */
public class NioServer {

    //创建服务器端通道对象
    private  static ServerSocketChannel serverSocketChannel;

    //多路复用器属性
    private  static Selector selector;

    public static void main(String[] args) throws IOException {

        //开启服务器端通道
        serverSocketChannel=ServerSocketChannel.open();
        //创建多路复用器
        selector=Selector.open();

        //绑定端口
        serverSocketChannel.bind(new InetSocketAddress(8080));

        serverSocketChannel.configureBlocking(false);

        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

        while (true){
            //设置为非阻塞IO,遍历事件,如果当前没有事件,则将当前线程设置为阻塞
            int select=selector.select();
            if (select==0){
                continue;
            }
            //遍历事件
            Set<SelectionKey> selectionKeys=selector.selectedKeys();

            Iterator<SelectionKey>  iterator=selectionKeys.iterator();

            SelectionKey  key=null;

            while (iterator.hasNext()){
                   key=iterator.next();
                   handle(key);
                   iterator.remove();
            }
        }
    }

    private static void handle(SelectionKey key) throws IOException {

        if (key.isValid()){
            if (key.isAcceptable()){
                ServerSocketChannel serverSocketChannel= (ServerSocketChannel) key.channel();
                SocketChannel socketChannel=serverSocketChannel.accept();
                socketChannel.configureBlocking(false);
                socketChannel.register(selector,SelectionKey.OP_READ);
            }

            if (key.isReadable()){
                SocketChannel socketChannel= (SocketChannel) key.channel();
                ByteBuffer  byteBuffer=ByteBuffer.allocate(1024);
                int read=socketChannel.read(byteBuffer);
                if (read>0){
                    byteBuffer.flip();
                    byte[] request=new byte[byteBuffer.remaining()];
                    byteBuffer.get(request);
                    System.out.println("zhangxiansheng input is :"+new String(request));
                    write(socketChannel,"ok");
                }
            }
        }
    }

    private static void write(SocketChannel socketChannel, String  response) throws IOException {

            if (response!=null&&response.length()>0) {

                byte[] bytes = response.getBytes();

                ByteBuffer  byteBuffer=ByteBuffer.allocate(1024);

                byteBuffer.put(bytes);

                byteBuffer.flip();

                socketChannel.write(byteBuffer);
            }
    }
}